﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;
using Microsoft.FSharp.Reflection;
using Microsoft.FSharp.Text.Lexing;

namespace TestApp
{
	public class SyntaxTree
	{
		private object _node;
		public List<SyntaxTree> Children { get; set; }
		public string Name { get; set; }
		public bool IsExpanded { get; set; }
		public bool IsSelected { get; set; }

		public SyntaxTree ( string name, object node )
		{
			_node = node;

			ExtractNodeInformation ( node );

			string nodeText = node is Position ? String.Format ( "{0},{1}", ( node as Position ).Column, ( node as Position ).Line ) : node.ToString ();

			Name = name + " : " + nodeText;
		}

		private void ExtractNodeInformation ( object node )
		{
			if ( !( _node is String ) && !( _node is int ) && !( _node is Position ) )
			{
				if ( _node is IEnumerable )
				{
					Children = new List<SyntaxTree> ();
					foreach ( object item in ( _node as IEnumerable ) )
						Children.Add ( new SyntaxTree ( item.ToString (), item ) );
				}
				else
				{
					if ( FSharpType.IsUnion ( _node.GetType (), null ) )
					{
						object[] value = FSharpValue.GetUnionFields ( _node, null, null ).Item2;
						Children = new List<SyntaxTree> ();
						foreach ( object item in value )
							Children.Add ( new SyntaxTree ( item.ToString (), item ) );
					}
					else
					{
						Children = node.GetType ().GetProperties ()
							.Where ( prop => prop.GetValue ( _node, null ) != null )
							.Select ( prop => new SyntaxTree ( prop.Name, prop.GetValue ( _node, null ) ) ).ToList ();
					}
				}
			}
		}
	}
}
